﻿using EasyCore.DependencyInjection.Interfaces;
using EasyCore.Entities;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace EasyCore.DependencyInjection
{
    /// <summary>
    /// 依赖注入
    /// </summary>
    public static class DependencyInjectionExtensions
    {
        /// <summary>
        /// 添加类型，到依赖注入内
        /// </summary>
        public static void AddTypes(this IServiceCollection services)
        {
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();//获得所有的程序集
            //获得所有能依赖注入的类型
            var errectiveTypes = assemblies.SelectMany(x => x.GetTypes());//获得所有的类型
            var canInjectTypes = errectiveTypes.Where(x => typeof(IPrivateDependency).IsAssignableFrom(x) && x.IsClass && !x.IsAbstract && x.IsInterface);//获得能依赖注入的类型
            //执行依赖注入
            foreach (var type in canInjectTypes)
            {
                var interfaces = type.GetInterfaces(); //获得类型的所有接口
                var canInjectInterfaces = interfaces.Where(x => x != typeof(IPrivateDependency) && x != typeof(ISingletonDependency)
                && x != typeof(IScopedDependency) && x != typeof(ITransientDependency) && x != typeof(IDisposable) && x != typeof(IAsyncDisposable)
                && ((!x.IsGenericType && !type.IsGenericType) || (x.IsGenericType && type.IsGenericType && x.GetGenericArguments().Length == type.GetGenericArguments().Length)));
                if (canInjectInterfaces == null || !canInjectInterfaces.Any())
                {
                    services.TryAdd(new ServiceDescriptor(type, type, GetServiceLifetime(type)));
                }
                else
                {
                    foreach (var item in canInjectInterfaces)
                    {
                        services.TryAdd(new ServiceDescriptor(item, type, GetServiceLifetime(type)));
                    }
                }
            }
        }

        /// <summary>
        /// 获得服务的生命周期
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static ServiceLifetime GetServiceLifetime(Type type)
        {
            if (type.IsAssignableFrom(typeof(ITransientDependency))) return ServiceLifetime.Transient;
            if (type.IsAssignableFrom(typeof(ISingletonDependency))) return ServiceLifetime.Singleton;
            return ServiceLifetime.Scoped;
        }
    }
}
